package com.econ.powercloud.ems.common.enums;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import java.util.*;
import java.util.stream.Collectors;

public enum CompanyType implements EnumMethod {

    /**  */
    MFRS(1,"生产厂家"),
    CONSUMER(2, "用户公司"),
    MAINENANCE(4,"运维公司"),
    MANAGER(8,"运营公司");

    private Integer code;
    private String desc;

    @Override
    public Integer getCode() {
        return code;
    }

    @Override
    public String getDesc() {
        return desc;
    }


    CompanyType(int code, String desc){
        this.code=code;
        this.desc=desc;
    }

    public static CompanyType parseCode(int code){
        for(CompanyType type: CompanyType.values()){
            if(type.getCode() == code){
                return type;
            }
        }
        return CONSUMER;
    }

    public static String fromCode(int code){
        for(CompanyType type: CompanyType.values()){
            if(type.getCode() == code){
                return type.getDesc();
            }
        }
        return null;
    }

    /**
     * 根据组合值 反推出枚举数组
     * @param combCode
     * @return
     */
    public static List<CompanyType> fromCombCode(Integer combCode){
        if (combCode == null) {
            return null;
        }
        List<CompanyType> list = new ArrayList<>();
        for(int i = 0; i < 4; i++){
            if((combCode >> i & 1) == 1){
                CompanyType companyType = parseCode(1 << i);
                list.add(companyType);
            }
        }
        return list;
    }

    /**
     * 组合类型是否包含某个类型
     * @param combCode
     * @param code
     * @return
     */
    public static boolean combCodeContainCode(Integer combCode, Integer code) {
        if (combCode == null || code == null) {
            return false;
        }
        return fromCombCode(combCode).stream().anyMatch(it -> Objects.equals(it.getCode(), code));
    }

    /**
     * 通过code组合出所有可能
     * @param code 肯定是枚举里的值
     * @return
     */
    public static Set<Integer> getCombsFromCode(Integer code) {
        if (code == null) {
            return null;
        }
        List<Integer> codes = Arrays.stream(CompanyType.values()).map(CompanyType::getCode).collect(Collectors.toList());
        Set<Integer> combsFromCodes = getCombsFromCodes(codes, Collections.singletonList(code));
        combsFromCodes.add(code);
        return combsFromCodes;
    }

    /**
     * 递归计算
     * @param allCodes
     * @param excludeCodes
     * @return
     */
    private static Set<Integer> getCombsFromCodes(List<Integer> allCodes, List<Integer> excludeCodes) {
        if (excludeCodes.size() == allCodes.size()) {
            return Sets.newHashSet();
        }
        Set<Integer> returnSets = Sets.newHashSet();
        int sum = excludeCodes.stream().mapToInt(it -> it).sum();
        for (Integer code : allCodes) {
            if (excludeCodes.contains(code)) {
                continue;
            }
            returnSets.add(sum + code);
            if (excludeCodes.size() == allCodes.size() - 1) {
                continue;
            }
            // 否则 还存在组合
            ArrayList<Integer> newExcludeCodes = Lists.newArrayList(excludeCodes);
            newExcludeCodes.add(code);
            returnSets.addAll(getCombsFromCodes(allCodes, newExcludeCodes));
        }
        return returnSets;
    }
}
